#!/usr/bin/env python3
"""增强版商品搜索爬虫命令行入口"""

import argparse
import sys
import os
import json
from datetime import datetime
from pathlib import Path
from typing import List, Dict

from rich.console import Console
from rich.table import Table
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.panel import Panel
from rich.text import Text
from rich.prompt import Confirm

from crawler.enhanced_spider import EnhancedSpider
from config.settings import Settings


def create_parser() -> argparse.ArgumentParser:
    """创建命令行参数解析器"""
    parser = argparse.ArgumentParser(
        description="增强版多平台商品搜索爬虫 - 支持智能登录绕过",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例用法:
  python enhanced_main.py --keyword "数据线" --pages 3
  python enhanced_main.py --keyword "手机壳" --platform taobao --pages 5 --output results.json
  python enhanced_main.py --keyword "充电器" --platform jd --no-guangzhou --no-sort
  python enhanced_main.py --keyword "电脑" --show-browser --verbose
        """
    )
    
    parser.add_argument(
        "--keyword", "-k",
        required=True,
        help="搜索关键词"
    )
    
    parser.add_argument(
        "--platform", "-pf",
        choices=["1688", "taobao", "jd"],
        default="1688",
        help="选择平台 (默认: 1688)"
    )
    
    parser.add_argument(
        "--pages", "-p",
        type=int,
        default=3,
        help="爬取页数 (默认: 3)"
    )
    
    parser.add_argument(
        "--output", "-o",
        help="输出文件名 (支持 .json 和 .csv 格式)"
    )
    
    parser.add_argument(
        "--format", "-f",
        choices=["json", "csv", "both"],
        default="json",
        help="输出格式 (默认: json)"
    )
    
    parser.add_argument(
        "--no-guangzhou",
        action="store_true",
        help="不筛选广州发货的商品"
    )
    
    parser.add_argument(
        "--no-sort",
        action="store_true",
        help="不按销量排序"
    )
    
    parser.add_argument(
        "--headless",
        action="store_true",
        default=True,
        help="使用无头浏览器模式 (默认开启)"
    )
    
    parser.add_argument(
        "--show-browser",
        action="store_true",
        help="显示浏览器窗口 (调试用)"
    )
    
    parser.add_argument(
        "--verbose", "-v",
        action="store_true",
        help="显示详细日志"
    )
    
    parser.add_argument(
        "--interactive", "-i",
        action="store_true",
        help="交互式模式"
    )
    
    return parser


def setup_output_dir() -> Path:
    """设置输出目录"""
    output_dir = Path("results")
    output_dir.mkdir(exist_ok=True)
    return output_dir


def generate_filename(keyword: str, platform: str, format_type: str) -> str:
    """生成输出文件名"""
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    safe_keyword = "".join(c for c in keyword if c.isalnum() or c in (' ', '-', '_')).strip()
    safe_keyword = safe_keyword.replace(' ', '_')
    return f"{platform}_{safe_keyword}_{timestamp}.{format_type}"


def display_results_table(products: List[Dict], console: Console, platform: str):
    """显示结果表格"""
    if not products:
        console.print("[red]没有找到符合条件的商品[/red]")
        return
    
    table = Table(title=f"搜索结果 - {platform.upper()}", show_header=True, header_style="bold magenta")
    table.add_column("序号", style="dim", width=4)
    table.add_column("商品名称", style="cyan", width=40)
    table.add_column("价格", style="green", width=12)
    
    # 根据平台显示不同的列
    if platform == "1688":
        table.add_column("销量", style="yellow", width=10)
        table.add_column("发货地", style="blue", width=10)
        table.add_column("供应商", style="magenta", width=20)
        table.add_column("起订量", style="red", width=10)
    else:
        table.add_column("销量", style="yellow", width=10)
        table.add_column("店铺", style="magenta", width=20)
    
    # 只显示前20个结果
    display_count = min(20, len(products))
    
    for i, product in enumerate(products[:display_count], 1):
        title = product.get('title', '')[:35] + "..." if len(product.get('title', '')) > 35 else product.get('title', '')
        price = product.get('price', 'N/A')
        sales = product.get('sales', 'N/A')
        
        if platform == "1688":
            location = product.get('location', 'N/A')
            supplier = product.get('supplier', '')[:15] + "..." if len(product.get('supplier', '')) > 15 else product.get('supplier', '')
            moq = product.get('moq', 'N/A')
            
            table.add_row(
                str(i),
                title,
                price,
                sales,
                location,
                supplier,
                moq
            )
        else:
            supplier = product.get('supplier', '')[:15] + "..." if len(product.get('supplier', '')) > 15 else product.get('supplier', '')
            
            table.add_row(
                str(i),
                title,
                price,
                sales,
                supplier
            )
    
    console.print(table)
    
    if len(products) > display_count:
        console.print(f"\n[dim]... 还有 {len(products) - display_count} 个商品未显示[/dim]")


def save_to_json(products: List[Dict], filepath: str, keyword: str, platform: str):
    """保存为JSON格式"""
    data = {
        "search_info": {
            "keyword": keyword,
            "platform": platform,
            "timestamp": datetime.now().isoformat(),
            "total_count": len(products)
        },
        "products": products
    }
    
    with open(filepath, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


def save_to_csv(products: List[Dict], filepath: str, platform: str):
    """保存为CSV格式"""
    import csv
    
    if not products:
        return
    
    # 根据平台确定字段
    if platform == "1688":
        fieldnames = ['title', 'price', 'sales', 'location', 'supplier', 'moq', 'link', 'image']
    else:
        fieldnames = ['title', 'price', 'sales', 'supplier', 'link', 'image']
    
    with open(filepath, 'w', newline='', encoding='utf-8') as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        
        for product in products:
            # 只写入存在的字段
            row = {field: product.get(field, '') for field in fieldnames}
            writer.writerow(row)


def interactive_mode(console: Console) -> Dict:
    """交互式模式"""
    console.print(Panel.fit(
        "[bold blue]交互式搜索模式[/bold blue]\n"
        "请按照提示输入搜索参数",
        title="欢迎"
    ))
    
    # 获取搜索关键词
    keyword = console.input("[cyan]请输入搜索关键词: [/cyan]")
    
    # 选择平台
    console.print("\n[yellow]可选平台:[/yellow]")
    console.print("1. 1688 (阿里巴巴)")
    console.print("2. 淘宝")
    console.print("3. 京东")
    
    platform_choice = console.input("\n[cyan]请选择平台 (1-3, 默认1): [/cyan]") or "1"
    platform_map = {"1": "1688", "2": "taobao", "3": "jd"}
    platform = platform_map.get(platform_choice, "1688")
    
    # 获取页数
    pages_input = console.input("[cyan]请输入爬取页数 (默认3): [/cyan]") or "3"
    try:
        pages = int(pages_input)
    except ValueError:
        pages = 3
    
    # 其他选项
    filter_guangzhou = not Confirm.ask("是否筛选广州发货的商品?", default=True)
    sort_by_sales = not Confirm.ask("是否按销量排序?", default=True)
    show_browser = Confirm.ask("是否显示浏览器窗口 (调试用)?", default=False)
    verbose = Confirm.ask("是否显示详细日志?", default=False)
    
    return {
        "keyword": keyword,
        "platform": platform,
        "pages": pages,
        "no_guangzhou": filter_guangzhou,
        "no_sort": sort_by_sales,
        "show_browser": show_browser,
        "verbose": verbose,
        "headless": not show_browser
    }


def main():
    """主函数"""
    parser = create_parser()
    args = parser.parse_args()
    
    console = Console()
    
    # 交互式模式
    if args.interactive:
        interactive_args = interactive_mode(console)
        # 更新args
        for key, value in interactive_args.items():
            setattr(args, key, value)
    
    # 平台信息映射
    platform_names = {
        "1688": "阿里巴巴1688",
        "taobao": "淘宝",
        "jd": "京东"
    }
    
    # 显示启动信息
    console.print(Panel.fit(
        f"[bold blue]增强版商品搜索爬虫[/bold blue]\n"
        f"搜索平台: [green]{platform_names.get(args.platform, args.platform)}[/green]\n"
        f"搜索关键词: [green]{args.keyword}[/green]\n"
        f"爬取页数: [yellow]{args.pages}[/yellow]\n"
        f"筛选广州: [cyan]{'是' if not args.no_guangzhou else '否'}[/cyan]\n"
        f"按销量排序: [magenta]{'是' if not args.no_sort else '否'}[/magenta]\n"
        f"浏览器模式: [blue]{'显示' if args.show_browser else '无头'}[/blue]",
        title="配置信息"
    ))
    
    # 设置输出目录
    output_dir = setup_output_dir()
    
    try:
        # 创建增强版爬虫实例
        headless = args.headless and not args.show_browser
        
        with Progress(
            SpinnerColumn(),
            TextColumn("[progress.description]{task.description}"),
            console=console
        ) as progress:
            
            task = progress.add_task("正在初始化爬虫...", total=None)
            
            with EnhancedSpider(
                platform=args.platform,
                headless=headless,
                verbose=args.verbose
            ) as spider:
                
                progress.update(task, description="正在搜索商品...")
                
                # 执行搜索
                products = spider.search_products(
                    keyword=args.keyword,
                    max_pages=args.pages,
                    filter_guangzhou=not args.no_guangzhou,
                    sort_by_sales=not args.no_sort
                )
            
            progress.update(task, description="搜索完成")
        
        # 显示结果
        console.print(f"\n[bold green]搜索完成！[/bold green]")
        console.print(f"找到 [bold yellow]{len(products)}[/bold yellow] 个商品")
        
        if products:
            # 显示结果表格
            display_results_table(products, console, args.platform)
            
            # 保存结果
            if args.output:
                output_file = output_dir / args.output
            else:
                output_file = None
            
            # 保存文件
            if args.format == "json" or args.format == "both":
                if output_file and output_file.suffix == ".json":
                    json_file = output_file
                else:
                    json_file = output_dir / generate_filename(args.keyword, args.platform, "json")
                save_to_json(products, str(json_file), args.keyword, args.platform)
                console.print(f"[green]JSON文件已保存: {json_file}[/green]")
            
            if args.format == "csv" or args.format == "both":
                if output_file and output_file.suffix == ".csv":
                    csv_file = output_file
                else:
                    csv_file = output_dir / generate_filename(args.keyword, args.platform, "csv")
                save_to_csv(products, str(csv_file), args.platform)
                console.print(f"[green]CSV文件已保存: {csv_file}[/green]")
            
            # 显示统计信息
            if args.platform == "1688" and not args.no_guangzhou:
                guangzhou_count = sum(1 for p in products if '广州' in p.get('location', ''))
                console.print(f"\n[blue]其中广州发货商品: {guangzhou_count} 个[/blue]")
            
            if not args.no_sort:
                console.print(f"[magenta]商品已按销量排序[/magenta]")
        
        else:
            console.print("[red]没有找到符合条件的商品[/red]")
            console.print("\n[yellow]建议:[/yellow]")
            console.print("• 尝试更换搜索关键词")
            console.print("• 检查网络连接")
            console.print("• 使用 --show-browser 参数查看浏览器状态")
    
    except KeyboardInterrupt:
        console.print("\n[yellow]用户中断操作[/yellow]")
        sys.exit(1)
    
    except Exception as e:
        console.print(f"[red]程序执行出错: {e}[/red]")
        if args.verbose:
            console.print_exception()
        sys.exit(1)


if __name__ == "__main__":
    main()